import 'dart:async';

import 'package:flutter/material.dart';
import 'package:yk_tools/yk_rtc_manager_delegate_mixin.dart';

export 'package:yk_tools/yk_rtc_manager_delegate_mixin.dart';

// 定义 IM 状态枚举
enum YkRtcMessageCallBackType {
  onError,
  onWarning,
  onCameraState,
  onMicState,
  onLocalRecordComplete,
  onRemoteUserState,
  onNetworkQuality,
  onTryToReconnect,
  onConnectionRecovery,
}

@immutable
class YkRtcManagerMessageModel {
  final YkRtcMessageCallBackType type;
  final dynamic params;

  const YkRtcManagerMessageModel({
    required this.type,
    required this.params,
  });
}

class YkRtcManager {
  static YkRtcManager? _instance;

  static YkRtcManager get instance {
    _instance ??= YkRtcManager._();
    return _instance!;
  }

  YkRtcManager._();

  YkRtcManagerDelegate? _delegate;
  final _messageController = StreamController<YkRtcManagerMessageModel>.broadcast();

  Stream<YkRtcManagerMessageModel> get messageStream => _messageController.stream;

  Future<void> config({required YkRtcManagerDelegate delegate}) async {
    _delegate = delegate;
    return Future.value();
  }

  Widget createWidget(Function(int viewId) onViewCreated) {
    return _delegate?.createWidget(onViewCreated) ?? const SizedBox();
  }
}

extension YkRtcManagerPublic on YkRtcManager {
  Future<void> init() async {
    return _delegate?.init(YkRtcManagerController(
      onError: (params) {
        _messageController.add(
          YkRtcManagerMessageModel(type: YkRtcMessageCallBackType.onError, params: params),
        );
      },
      onWarning: (params) {
        _messageController.add(
          YkRtcManagerMessageModel(type: YkRtcMessageCallBackType.onWarning, params: params),
        );
      },
      onCameraState: (uid, isOpen) {
        _messageController.add(
          YkRtcManagerMessageModel(type: YkRtcMessageCallBackType.onCameraState, params: {
            "uid": uid,
            "isOpen": isOpen,
          }),
        );
      },
      onMicState: (uid, isOpen) {
        _messageController.add(
          YkRtcManagerMessageModel(type: YkRtcMessageCallBackType.onMicState, params: {
            "uid": uid,
            "isOpen": isOpen,
          }),
        );
      },
      onLocalRecordComplete: (path) {
        _messageController.add(
          YkRtcManagerMessageModel(type: YkRtcMessageCallBackType.onLocalRecordComplete, params: {
            "path": path,
          }),
        );
      },
      onRemoteUserState: (String userId, bool isLeave) {
        _messageController.add(
          YkRtcManagerMessageModel(type: YkRtcMessageCallBackType.onRemoteUserState, params: {
            "uid": userId,
            "isLeave": isLeave,
          }),
        );
      },
      onNetworkQuality: (remoteQuality) {
        _messageController.add(
          YkRtcManagerMessageModel(type: YkRtcMessageCallBackType.onNetworkQuality, params: {
            "remoteQuality": remoteQuality,
          }),
        );
      },
      onTryToReconnect: () {
        _messageController.add(const YkRtcManagerMessageModel(type: YkRtcMessageCallBackType.onTryToReconnect, params: {}));
      },
      onConnectionRecovery: () {
        _messageController.add(const YkRtcManagerMessageModel(type: YkRtcMessageCallBackType.onConnectionRecovery, params: {}));
      },
    ));
  }

  Future login({dynamic params}) {
    return _delegate?.login(params) ?? Future.value();
  }

  Future logout({dynamic params}) {
    return _delegate?.logout(params) ?? Future.value();
  }

  Future<void> enterRoom({required String roomId, bool isLive = false, dynamic params}) async {
    await _delegate?.enterRoom(roomId, isLive, params);
    return Future.value();
  }

  Future<void> exitRoom({required String roomId, dynamic params}) async {
    await _delegate?.exitRoom(params);
    return Future.value();
  }

  Future<void> openSpeaker({required bool isOpen}) async {
    await _delegate?.openSpeaker(isOpen);
    return Future.value();
  }

  Future<void> switchRole({required bool isAnchor}) async {
    await _delegate?.switchRole(isAnchor);
    return Future.value();
  }

  Future<void> openMic({required bool isOpen}) async {
    await _delegate?.openMic(isOpen);
    return Future.value();
  }

  Future<void> startStreaming() async {
    await _delegate?.startStreaming();
    return Future.value();
  }

  Future<void> stopStreaming() async {
    await _delegate?.stopStreaming();
    return Future.value();
  }

  Future<void> startLocalPreview({required int viewId, bool frontCamera = false}) async {
    await _delegate?.startLocalPreview(frontCamera, viewId);
    return Future.value();
  }

  Future<void> startRemoteView({required String userId, required int viewId}) async {
    await _delegate?.startRemoteView(userId, viewId);
    return Future.value();
  }

  ///停止远端视频拉流
  Future<void> stopRemoteView({required String userId}) async {
    await _delegate?.stopRemoteView(userId);
    return Future.value();
  }

  ///停止本地视频推流
  Future<void> stopLocalPreview() async {
    await _delegate?.stopLocalPreview();
    return Future.value();
  }

  ///切换摄像头
  Future<int?> changeCamera({required bool frontCamera}) async {
    return await _delegate?.changeCamera(frontCamera);
  }

  Future<void> dispose() async {
    await _delegate?.dispose();
    _delegate = null;
    return Future.value();
  }
}